using System;
using System.Collections.Generic;
using System.Text;

using SchEdu.Framework.Algorithm;
using SchEdu.Framework.DataModel;
using SchEdu.Framework.Exceptions;
using SchEdu.Framework.Validators;

namespace Moore
{
    public class MooreAlgorithm : Algorithm
    {
        public MooreAlgorithm() 
            : base()
        {
        }
        public MooreAlgorithm(SchEduData schEduData)
            : base(schEduData)
        {
        }

        protected override void InitializeValidators()
        {
            base.InitializeValidators();

            validators.Add(new OrderDueDateValidator(SchEduData));
            validators.Add(new WorkCenterValidator(SchEduData, 1, 1));
            validators.Add(new OperationPerOrderValidator(SchEduData, 1, 1));
        }

        protected override void Logic()
        {
            OperationList partialScheduledOperations = new OperationList();
            OperationList operationWithGreatestProcessinTime = new OperationList();

            SchEduDataSet.WorkCenterRow workCenter = SchEduData.WorkCenter[0];
            SchEduDataSet.MachineRow machine = SchEduData.Machine[0];

            SchEduDataSet.OperationRow maxProcessingTime;

            // Sort operations by EDD
            Operations.SortByEDD();

            // set start date, end date and assign the work center and machine to operations
            SetOperationDates();

            foreach (SchEduDataSet.OperationRow op in Operations)
            {
                // Add operation to the partial scheduled list
                partialScheduledOperations.Add(op);

                // check if operation is late
                if (op.EndDate > op.OrderRow.DueDate)
                {
                    continue;
                }
                // Operation is late, remove the operation with the greatest processing time and move to operationWithGreatestProcessinTime list
                maxProcessingTime = partialScheduledOperations.MaxProcessingTime();
                partialScheduledOperations.Remove(maxProcessingTime);
                operationWithGreatestProcessinTime.Add(maxProcessingTime);
            }

            Operations.Clear();
            Operations.AddRange(partialScheduledOperations);
            Operations.AddRange(operationWithGreatestProcessinTime);

            // recalculate their start dates and end dates
            SetOperationDates();

        }

        public override AboutInfo AboutInfo
        {
            get
            {
                AboutInfo aboutInfo = new AboutInfo();
                aboutInfo.Title = "Moore";
                aboutInfo.Description = Resource.MooreAlgorithmDescription;
                aboutInfo.Guid = new Guid("{E7EA2F83-F6CC-4360-BC80-2A4E57489742}");
                return aboutInfo;
            }
        }

    }
}
